package controllers;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import models.EEntity;
import models.Idea;
import models.Organization;
import models.Plan;
import models.Role;
import models.RoleInOrganization;
import models.Topic;
import models.User;
import play.mvc.Controller;

public class Export extends Controller {

	/**
	 * @author AkrAmAtion
	 * 
	 * @param id
	 *            is the user id of the user that performed the search
	 * @param searchKeyWord
	 *            is the searchKeyWord that the user entered. This parameter is
	 *            used to get the results set from the cache. The user id and
	 *            the search keyword are hashed and used as the key of the
	 *            results set.
	 * 
	 *            The method renders the file to the user or an error page if
	 *            the file is corrupted.
	 * */
	public static void exportCSV(String searchKeyWord) {
		File f = null;
		FileWriter fw = null;
		boolean corrupted = false;
		boolean isLoggedIn = false;
		String userName = session.get("username");
		User loggedInUser = User.find("byUserName", userName).first();
		long id = -1;
		if (loggedInUser != null && loggedInUser != null) {
			isLoggedIn = true;
			id = loggedInUser.id;
		}
		List<Object> hashObj = new LinkedList<Object>();
		hashObj.add(id);
		hashObj.add(searchKeyWord);
		String key = hashObj.hashCode() + "";
		List results = (List) play.cache.Cache.get(key);
		if (results == null) {
			corrupted = true;
		}
		if (!corrupted) {
			f = new File("\\SearchResults"/* + key*/ + ".csv");
			try {
				fw = new FileWriter(f);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				corrupted = true;
			}
		}
		if (!corrupted && fw != null) {
			System.out.println("analyzing results");
			for (int i = 0; i < results.size(); i++) {
				if (results.get(i) == null)
					continue;
				switch (i) {
				case 0:
				case 1:
					for (Idea idea : (List<Idea>) results.get(i))
						if (!(idea.topic.entity.organization.isSecret())
								|| (isLoggedIn && idea.topic.entity.organization
										.isMember(id))) {
							try {
								fw.append(idea.toString() + "\n");
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
								corrupted = true;
							}
						}
					break;
				case 2:
					for (Organization org : (List<Organization>) results.get(i)) {
						if (!org.isSecret() || (isLoggedIn && org.isMember(id))) {
							try {
								fw.append(org.toString() + "\n");
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
								corrupted = true;
							}
						}
					}
					break;
				case 3:
				case 4:
					for (EEntity entity : (List<EEntity>) results.get(i)) {
						if (!entity.organization.isSecret()
								|| (isLoggedIn && entity.organization
										.isMember(id))) {
							try {
								fw.append(entity.toString() + "\n");
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
								corrupted = true;
							}
						}
					}
					break;
				case 5:
					for (Plan plan : (List<Plan>) results.get(i)) {
						List<Organization> allowedOrg = new LinkedList<Organization>();
						for (Idea implementing : plan.ideas) {
							allowedOrg
									.add(implementing.topic.entity.organization);
						}
						for (Organization org : allowedOrg) {
							if (isLoggedIn && org.isMember(id)) {
								try {
									fw.append(plan.toString() + "\n");
								} catch (IOException e) {
									e.printStackTrace();
									corrupted = true;
								}
								break;
							}
						}
					}
					break;
				case 6:
				case 7:
					for (Topic topic : (List<Topic>) results.get(i)) {
						if (topic.status < 2
								&& (!topic.entity.organization.isSecret()
										&& !topic.entity.organization
												.isPrivate() || isLoggedIn
										&& topic.entity.organization
												.isMember(id))) {
							try {
								fw.append(topic.toString() + "\n");
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
								corrupted = true;
							}
						}
					}
				}
			}
		}
		try {
			fw.flush();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			corrupted = true;
		}
		String path;
		if (f == null)
			path = "";
		else
			path = f.getPath();
		path = "localhost:9000/export" + path.replace('\\', '/');
		render(corrupted, path);
	}

}
